package umls.expander;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import jdbc.UMLS_DB_Interface;
import umls.data.jaxb.ExpandedTermsType;
import umls.data.jaxb.TermType;

public class GenKeywords {
	String hostname = "jdbc:mysql://130.192.163.27:3306/";
	String semtypeconfilename;
	String username = "abate";
	String password = "7prova7";
	String dbname = "umls";
	UMLS_DB_Interface umlsdb;
	TreeMap<String, String> ExpandedGenes;
	TreeMap<String, String> ExpandedBiologicalProcesses;
	Keyword keygenerator;
	SemGroupConfReader sgcr;
	ArrayList<String> EG;
	static JAXBContext jc;
	static Marshaller m;

	public GenKeywords(String conffilename, List<String> expanGroups) {
		

		String semtypeconfilename = conffilename;
		ExpandedGenes = new TreeMap<String, String>();
		ExpandedBiologicalProcesses = new TreeMap<String, String>();

		EG = new ArrayList<String>();

		keygenerator = new Keyword();
		umlsdb = new UMLS_DB_Interface();

		try {
			umlsdb.SetUpConnection(hostname, username, password, dbname);
		} catch (ClassNotFoundException e1) {
			System.out.println("ERRORE: driver Mysql non trovati");
			// e1.printStackTrace();
		} catch (SQLException e1) {
			System.out.println("ERRORE: connessione Mysql non valida");
		}

		sgcr = new SemGroupConfReader(semtypeconfilename);

		//sgcr.ReadAllowedSemanticGroups();
		sgcr.setAllowedSemanticGroups(expanGroups);
		sgcr.ReadAllowedSemanticTypes();

		try {
			jc = JAXBContext.newInstance("umls.data.jaxb");
			m = jc.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		} catch (JAXBException e) {
			
			e.printStackTrace();
		}
	}




	public List<String> generate(String gene, String process)
			throws SQLException {
		// System.out.println("Dentro il modulo di espansione: inizio");
		if (gene != null && process != null) {
			try {

				ExpandedGenes.put(gene, keygenerator
						.GetKeywordBySingleBiologicalProcessFilteredBySemType(
								gene, umlsdb, sgcr));
				// System.out.println("Dentro il modulo di espansione: "+ExpandedGenes.size()+" geni inseriti");
			} catch (NullPointerException e) {
				// TODO Auto-generated catch block
				System.out
						.println("ERRORE: connessione Mysql non valida durante la generazione dei geni: puntatore null");
				return new ArrayList<String>();
			}
			// ExpandedGenes.put(genes[i],
			// keygenerator.GetKeywordBySingleGene(genes[i], umlsdb));

		}

		if (process != null) {
			try {
				ExpandedBiologicalProcesses.put(process, keygenerator
						.GetKeywordBySingleBiologicalProcessFilteredBySemType(
								process, umlsdb, sgcr));
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				System.out
						.println("ERRORE: connessione Mysql non valida durante la generazione dei processi");
			}

		}
		try {
			umlsdb.CloseConnection();
		} catch (SQLException e) {
			System.out
					.println("ERRORE: impossibile chiudere la connessione mysql: tuttavia continuo l'esecuzione");
		}
		return getExpandedData(process, ExpandedGenes, ExpandedBiologicalProcesses);
	}

	public static ExpandedTermsType getXmlData(String bioproc,
			TreeMap<String, String> ExpandedGenes,
			TreeMap<String, String> ExpandedBiologicalProcesses) {
		// StringBuilder result = new StringBuilder();
		ArrayList<String> EP = new ArrayList<String>();
		Set bioproc_set = ExpandedBiologicalProcesses.entrySet();
		Iterator bioproc_it = bioproc_set.iterator();

		while (bioproc_it.hasNext()) {
			@SuppressWarnings("unchecked")
			Map.Entry<String, String> entrybioproc = (Map.Entry<String, String>) bioproc_it
					.next();
			// System.out.println(entrybioproc.getValue());
			String[] EP_splitted = entrybioproc.getValue().split("\n");

			for (int i = 0; i < EP_splitted.length; i++) {
				EP.add(EP_splitted[i].replace(",", ""));
			}
		}

		// each EP is combined with each gene and process
		Iterator<String> genes_it = ExpandedGenes.keySet().iterator();
		ExpandedTermsType e_terms = new ExpandedTermsType();

		while (genes_it.hasNext()) {
			String gene = genes_it.next();

			Iterator<String> EP_it = EP.iterator();
			while (EP_it.hasNext()) {
				TermType term = new TermType();
				// System.out.println("Dentro il modulo di espansione: itero i geni");
				String EP_next = EP_it.next();
				// System.out.println("Term aggiunto");
				term.setTerm1(bioproc);
				term.setTerm2(gene);
				term.setTerm3(EP_next);
				e_terms.getTerm().add(term);

			}
		}

		// result.append(NEW_LINE + "\n\n\nfase nuova\n\n\n" + NEW_LINE);

		// with the process, each gene is combined with each EG belonging to the
		// EG set of the current gene
		genes_it = ExpandedGenes.keySet().iterator();

		while (!genes_it.hasNext()) {
			String gene = genes_it.next();

			String expandedgenes = ExpandedGenes.get(gene);

			String[] geneset = expandedgenes.split("\n");

			for (int i = 0; i < geneset.length; i++) {
				// System.out.println("Term aggiunto");
				TermType term = new TermType();
				term.setTerm1(bioproc);
				term.setTerm2(gene);
				term.setTerm3(geneset[i]);
				e_terms.getTerm().add(term);
			}

		}
		// JAXBElement<ExpandedTermsType> e_terms_element = (new
		// ObjectFactory()).createExpandedTerms(e_terms);
		return e_terms;
	}
	
	public static List<String> getExpandedData(String bioproc,
			TreeMap<String, String> ExpandedGenes,
			TreeMap<String, String> ExpandedBiologicalProcesses) {
		// StringBuilder result = new StringBuilder();
		ArrayList<String> EP = new ArrayList<String>();
		Set bioproc_set = ExpandedBiologicalProcesses.entrySet();
		Iterator bioproc_it = bioproc_set.iterator();

		while (bioproc_it.hasNext()) {
			@SuppressWarnings("unchecked")
			Map.Entry<String, String> entrybioproc = (Map.Entry<String, String>) bioproc_it
					.next();
			// System.out.println(entrybioproc.getValue());
			String[] EP_splitted = entrybioproc.getValue().split("\n");

			for (int i = 0; i < EP_splitted.length; i++) {
				EP.add(EP_splitted[i].replace(",", ""));
			}
		}

		// each EP is combined with each gene and process
		Iterator<String> genes_it = ExpandedGenes.keySet().iterator();
		List<String> results = new LinkedList<String>();
		while (genes_it.hasNext()) {
			String gene = genes_it.next();

			Iterator<String> EP_it = EP.iterator();
			while (EP_it.hasNext()) {
				String EP_next = EP_it.next();
				// System.out.println("Term aggiunto");
				results.add(EP_next);

			}
		}
		genes_it = ExpandedGenes.keySet().iterator();

		while (!genes_it.hasNext()) {
			String gene = genes_it.next();

			String expandedgenes = ExpandedGenes.get(gene);

			String[] geneset = expandedgenes.split("\n");
			for (int i = 0; i < geneset.length; i++) {
				results.add(geneset[i]);
			}

		}
		return results;
	}
	
	

}
